package paskal.audio.player;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.URLConnection;

public class CashingThread extends Thread {
	private CashedPlayer player;

	private InputStream in;
	private RandomAccessFile file;
	private boolean playFlag = false;
	private boolean isEnabled = true;
	private boolean deleteFlag = false;
	private boolean isCashed = false;
	private int offset = 0;
	private File tempFile;
	public static int CASH_BUFFER_SIZE = 4096 * 4;
	boolean isOpened = false;
	private double loadPercentage = 0;

	public CashingThread(URLConnection connection, CashedPlayer player) {
		this.player = player;
		try {

			in = connection.getInputStream();

			if ((tempFile == null) || (!tempFile.exists())) {
				tempFile = File.createTempFile("relax_player_audio", ".temp");
			}
			file = new RandomAccessFile(tempFile, "rw");
			file.setLength(connection.getContentLength());
		} catch (IOException e) {
			player.setStatus(CashedPlayer.STOPPED);
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		int numberOfBytesRead = 0;
		byte[] buffer = new byte[CASH_BUFFER_SIZE];
		boolean isCashing = false;
		if (in == null)
			isEnabled = false;
		while (isEnabled) {
			try {
				numberOfBytesRead = in.read(buffer, 0, buffer.length);
				if (numberOfBytesRead == -1) {
					break;
				}
				file.write(buffer, 0, numberOfBytesRead);

				offset = (int) file.getFilePointer();
				loadPercentage = offset * 1.0 / file.length();

				if (player != null) {
					double diff = loadPercentage
							- player.getPercentagePosition();

					if (diff <= 0.02) {
						if (!isCashing) {
							isCashing = true;
							player.notifyListener(PlayerEvent.CAHSING,
									loadPercentage, -1, null);
						}
						try {
							player.pause();
						} catch (PlayerException e) {
							e.printStackTrace();
						}
					} else if (isCashing && (diff >= 0.05)) {
						isCashing = false;
						player.notifyListener(PlayerEvent.CAHSED,
								loadPercentage, -1, null);
						try {
							player.resume();
						} catch (PlayerException e) {
							e.printStackTrace();
						}
					}

					if ((!isOpened) && (loadPercentage > 0.05)) {
						isOpened = true;
						try {
							player.open(tempFile);
						} catch (PlayerException e) {
							e.printStackTrace();
						}
					} else if (playFlag && isOpened && (!isCashing)) {
						playFlag = false;
						try {
							player.startPlayback();
						} catch (PlayerException e) {
							e.printStackTrace();
						}
					}
					if (player.getListener() != null) {
						player.getListener().onLoading(loadPercentage);
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
				break;
			}
		}
		if (in != null) {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		isCashed = true;
		deleteFlag = true;
		if (!isEnabled) {
			if ((tempFile != null) && tempFile.exists())
				tempFile.delete();
		}
	}

	public void disable() {
		isEnabled = false;
		player = null;
		if (deleteFlag) {
			if ((tempFile != null) && tempFile.exists())
				tempFile.delete();
		}
	}

	public void clearCash() {
		if ((tempFile != null) && tempFile.exists())
			tempFile.delete();
	}

	public File getTempFile() {
		return tempFile;
	}

	public boolean isEnabled() {
		return isEnabled;
	}

	public void playAsapPlease() {
		if (!isCashed) {
			playFlag = true;
		} else {
			try {
				playFlag = false;
				player.startPlayback();
			} catch (PlayerException e) {
				e.printStackTrace();
			}
		}
	}

	public double getLoadPercentage() {
		return loadPercentage;
	}

	public void setLoadPercentage(double loadPercentage) {
		this.loadPercentage = loadPercentage;
	}
}